diff options
Diffstat (limited to 'src/routes/(app)/[username]/(profile)/+page.svelte')
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/+page.svelte | 229 |
1 files changed, 175 insertions, 54 deletions
diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte index baab8ba1..168556e4 100644 --- a/src/routes/(app)/[username]/(profile)/+page.svelte +++ b/src/routes/(app)/[username]/(profile)/+page.svelte @@ -1,76 +1,197 @@ <script> - import { Avatar, Balance, Feed } from '$comp'; + import { onMount } from 'svelte'; + import { Icon, Avatar, Balance, Feed } from '$comp'; import { t } from '$lib/translations'; import { f, sat, sats } from '$lib/utils'; + import { sign, send, encrypt, decrypt } from '$lib/nostr'; + import { event as e, password } from '$lib/store'; + import { browser } from '$app/environment'; export let data; - let { events, invoices, sent, received, subject, user } = data; - console.log(invoices); + let { messages, notes, invoices, sent, received, subject, user } = data; + $: refresh(data); + let refresh = (d) => ({ messages, notes, invoices, sent, received, subject, user } = d); + + let keys = new Set(); + let latest = []; + let i = 0; + let ready; + + e.subscribe(async (event) => { + if (!(event && ready)) return; + if (event.recipient.id === user?.id && !~latest.findIndex((m) => m.id === event.id)) { + event.content = await decrypt({ event, user }); + + let i = latest.findIndex((m) => m.pubkey === event.pubkey); + let popped; + if (~i) popped = latest.splice(i, 1); + else popped = latest.pop(); + + latest.unshift(event); + latest = latest; + } + }); + + $: initialize($password); + let initialize = async (p) => { + ready = false; + if (!p) return; + while (latest.length < 3 && i < messages.length) { + let event = messages[i]; + let k = event.author.id === user.id ? event.recipient.pubkey : event.author.pubkey; + if (!keys.has(k)) { + keys.add(k); + event.content = await decrypt({ event, user }); + if (event.content) latest.push(event); + } + i++; + } + + latest = latest; + ready = true; + }; </script> -<div class="flex justify-center lg:justify-start"> +<div class="space-y-8"> {#if user?.id === subject.id} - <Balance {user} /> - {/if} -</div> + <div> + <div class="flex justify-center lg:justify-start"> + <Balance {user} /> + </div> + {#if !user.balance} + <div class="space-y-8 mt-8"> + <p class="text-secondary text-lg"> + Welcome! Your account balance is empty. You can start by making a deposit or by asking + someone to pay you. + </p> -<div> - {#each invoices as { amount, currency, rate, request: { requester, recipient }, hash }} - {@const requested = user.username === requester?.username} - <a href={`/${recipient.username}/invoice/${hash}` + (requested ? '/tip' : '')}> - <div class="border-b p-2 last:border-b-0 hover:bg-gray-100"> - <div class="flex gap-2"> - <div> - {#if requested} - <div class="flex"> - <Avatar user={recipient} size={20} /> - <div class="my-auto text-left"> - <p class="text-secondary">{$t('payments.invoiceFrom')}</p> - <p class="ml-1 text-lg break-words">{recipient.username}</p> + <div class="flex gap-4 justify-center w-full"> + <a href={`/${user.username}/receive`}> + <button + class="rounded-full border py-3 px-6 font-bold hover:opacity-80 flex w-60 bg-black text-white" + > + <div class="mx-auto flex"> + <Icon icon="numpad" style="my-auto h-6 mr-2 invert" /> + <div class="my-auto mt-1">Request Payment</div> </div> + </button> + </a> + + {#if user.eligible} + <a href={`/buy`}> + <button class="rounded-full border py-3 px-6 font-bold hover:opacity-80 flex w-60"> + <div class="mx-auto flex"> + <!-- <Icon icon="plus" style="my-auto h-6 mr-2" /> --> + + <img + src="/images/bitcoin.svg" + class="w-8 border-4 border-transparent mr-2" + alt="Bitcoin" + /> + <div class="my-auto mt-1">Buy Bitcoin</div> + </div> + </button> + </a> + {/if} + </div> + </div> + {/if} + </div> + {/if} + + {#if invoices.length} + <div> + <h1 class="text-secondary text-xl">Invoices</h1> + {#each invoices as { amount, currency, rate, request: { requester, recipient }, hash }} + {@const requested = user.username === requester?.username} + <a href={`/${recipient.username}/invoice/${hash}` + (requested ? '/tip' : '')}> + <div class="border-b p-2 last:border-b-0 hover:bg-gray-100"> + <div class="flex gap-2"> + <div> + {#if requested} + <div class="flex"> + <Avatar user={recipient} size={20} /> + <div class="my-auto text-left"> + <p class="text-secondary">{$t('payments.invoiceFrom')}</p> + <p class="ml-1 text-lg break-words">{recipient.username}</p> + </div> + </div> + {:else} + <div class="flex"> + <Avatar user={requester} size={20} /> + <div class="my-auto text-left"> + <p class="text-secondary">{$t('payments.awaiting')}</p> + <p class="ml-1 text-lg break-words">{requester.username}</p> + </div> + </div> + {/if} </div> - {:else} - <div class="flex"> - <Avatar user={requester} size={20} /> - <div class="my-auto text-left"> - <p class="text-secondary">{$t('payments.awaiting')}</p> - <p class="ml-1 text-lg break-words">{requester.username}</p> + <div class="whitespace-nowrap my-auto ml-auto flex gap-2"> + <div class="font-bold"> + {f(amount * (rate / sats), currency)} </div> + + <div class="text-secondary">{sat(amount)}</div> </div> - {/if} - </div> - <div class="whitespace-nowrap my-auto ml-auto flex gap-2"> - <div class="font-bold"> - {f(amount * (rate / sats), currency)} </div> - - <div class="text-secondary">{sat(amount)}</div> </div> - </div> - </div> - </a> - {/each} + </a> + {/each} + </div> + {/if} + {#if received.length} + <div> + <h1 class="text-secondary text-xl">Requests</h1> - {#each received as { id, invoice, memo, requester: r }} - <a href={`/${user.username}/receive/${id}`}> - <div class="border-b p-2 last:border-b-0 hover:bg-gray-100"> - <div class="flex"> - <div> + {#each received as { id, invoice, memo, requester: r }} + <a href={`/${user.username}/receive/${id}`}> + <div class="border-b p-2 last:border-b-0 hover:bg-gray-100"> <div class="flex"> - <Avatar user={r} size={20} /> - <div class="my-auto text-left"> - <p class="ml-1 text-lg break-words">{r.username}</p> - <p class="ml-1 text-secondary">{memo}</p> + <div> + <div class="flex"> + <Avatar user={r} size={20} /> + <div class="my-auto text-left"> + <p class="ml-1 text-lg break-words">{r.username}</p> + <p class="ml-1 text-secondary">{memo}</p> + </div> + </div> + </div> + <div class="whitespace-nowrap my-auto ml-auto flex gap-2"> + <button class="rounded-full border py-2 px-4 font-bold hover:opacity-80 w-full" + >Invoice</button + > </div> </div> </div> - <div class="whitespace-nowrap my-auto ml-auto flex gap-2"> - <button class="rounded-full border py-2 px-4 font-bold hover:opacity-80 w-full" - >Invoice</button - > + </a> + {/each} + </div> + {/if} + + {#if latest.length && user?.id === subject.id} + <div class="relative"> + {#each latest as { content, pubkey, author, recipient }} + {@const user = author.id === user.id ? recipient : author} + <a href={`/${user.username}/messages`}> + <div class="flex hover:bg-gray-100 p-4 rounded-2xl"> + <div class="my-auto"> + <Avatar {user} size={'20'} disabled={true} /> + </div> + <div class="my-auto truncate"> + <div class="my-auto ml-1 text-lg font-bold">{user.username}</div> + <div class="my-auto ml-1 text-secondary text-lg truncate"> + {content} + </div> + </div> </div> - </div> - </div> - </a> - {/each} + </a> + {/each} + </div> + {/if} </div> + +<style> + h1 { + @apply mb-2; + } +</style> |
